#include "Client.h"

Client::Client(FenPrincipale *fenetrePrincipale)
{ 
    this->fenetrePrincipale = fenetrePrincipale;
    socket = new QTcpSocket(this);
    maSocketClient = new MaSocketClient(socket, this);

    layout = new QVBoxLayout(this);

    etat = new QLabel(this);
    QFont font("System", 14);
    etat->setFont(font);
    etat->setText("<font color=#C60003>Déconnecté</font>");

    zoneText = new QTextEdit(this);
    zoneText->setReadOnly(true);
    zoneText->setMinimumHeight(100);

    // déconnecté.
    widgetDeconnecte = new QWidget(this);
    layoutDeconnecte = new QGridLayout(widgetDeconnecte);
    layoutDeconnecte->setContentsMargins(2,2,2,2);
    monBoutonPushManuel = new MonBoutonPush("Connexion manuelle", widgetDeconnecte);
    monBoutonPushManuel->setToolTip("Passer en mode connexion manuelle");
    monBoutonPushManuel->setStatusTip("Passe en mode connexion manuelle");
    monBoutonPushManuel->setTaillePolice(9);
    monBoutonPushProfil = new MonBoutonPush("Connexion par profil", widgetDeconnecte);
    monBoutonPushProfil->setToolTip("Passer en mode connexion par profil");
    monBoutonPushProfil->setStatusTip("Passe en mode connexion par profil");
    monBoutonPushProfil->setTaillePolice(9);
    monBoutonPushProfil->setDisabled(true);
    // déconnecté - manuel
    widgetDeconnecteManuel = new QWidget(widgetDeconnecte);
    layoutDeconnecteManuel = new QFormLayout(widgetDeconnecteManuel);
    widgetDeconnecteManuel->setLayout(layoutDeconnecteManuel);
    ip = new QLineEdit(widgetDeconnecteManuel);
    ip->setText("127.0.0.1");
    port = new QLineEdit(widgetDeconnecteManuel);
    port->setText("50885");
    pass = new QLineEdit(widgetDeconnecteManuel);
    nick = new QLineEdit(widgetDeconnecteManuel);
    layoutDeconnecteManuel->setSpacing(5);
    layoutDeconnecteManuel->addRow("&Ip", ip);
    layoutDeconnecteManuel->addRow("&Port", port);
    layoutDeconnecteManuel->addRow("&Mot de passe", pass);
    layoutDeconnecteManuel->addRow("P&seudo", nick);
    widgetAjoutProfil = new QWidget(widgetDeconnecteManuel);
    nomProfil = new QLineEdit(widgetAjoutProfil);
    monBoutonPushAjoutProfil = new MonBoutonPush("Ajouter", widgetAjoutProfil, ":/png/ajout");
    monBoutonPushAjoutProfil->setToolTip("Ajouter ce profil à la liste");
    monBoutonPushAjoutProfil->setStatusTip("Ajoute le profil à la liste");
    monBoutonPushAjoutProfil->setTaillePolice(9);
    monBoutonPushCo = new MonBoutonPush("Se connecter", widgetDeconnecteManuel, ":/png/co");
    monBoutonPushCo->setToolTip("Se connecter au serveur");
    monBoutonPushCo->setStatusTip("Vous connecte au serveur");
    layoutDeconnecteManuel->addWidget(monBoutonPushCo);
    ajoutProfilLayout = new QVBoxLayout(widgetAjoutProfil);
    ajoutProfilLayout->addWidget(nomProfil);
    ajoutProfilLayout->addWidget(monBoutonPushAjoutProfil);
    widgetAjoutProfil->setLayout(ajoutProfilLayout);
    layoutDeconnecteManuel->addRow("Ajouter aux profils",  widgetAjoutProfil);
    widgetDeconnecteManuel->setVisible(false);

    // déconnecté - profils
    widgetDeconnecteProfil = new QWidget(widgetDeconnecte);
    layoutDeconnecteProfil = new QVBoxLayout(widgetDeconnecteProfil);
    widgetDeconnecteProfil->setLayout(layoutDeconnecteProfil);
    labelListeProfils = new QLabel("Liste des profils :", widgetDeconnecteProfil);
    listeProfils = new QTreeView(widgetDeconnecteProfil);
    layoutDeconnecteProfil->addWidget(labelListeProfils);
    layoutDeconnecteProfil->addWidget(listeProfils);


    layoutDeconnecte->addWidget(widgetDeconnecteManuel, 0, 0, 1, 2);
    layoutDeconnecte->addWidget(widgetDeconnecteProfil, 1, 0, 1, 2);
    layoutDeconnecte->addWidget(monBoutonPushManuel, 2, 0);
    layoutDeconnecte->addWidget(monBoutonPushProfil, 2, 1);
    widgetDeconnecte->setLayout(layoutDeconnecte);

    // connecté.
    widgetConnecte = new QWidget(this);
    layoutConnecte = new QVBoxLayout(widgetConnecte);
    listeClients = new QTreeView(widgetConnecte);
    monBoutonPushDeco = new MonBoutonPush("Se déconnecter", widgetConnecte, ":/png/deco");
    monBoutonPushDeco->setToolTip("Se déconnecter du serveur");
    monBoutonPushDeco->setStatusTip("Vous déconnecte du serveur");
    layoutConnecte->addWidget(listeClients);
    layoutConnecte->addWidget(monBoutonPushDeco);
    widgetConnecte->setLayout(layoutConnecte);

    layout->addWidget(etat);
    layout->addWidget(zoneText);
    layout->addWidget(widgetConnecte);
    layout->addWidget(widgetDeconnecte);
    widgetConnecte->hide();
    setLayout(layout);

    settingsListeProfils = new SettingsListeProfils(this, ip, port, pass, nick, nomProfil, listeProfils);

    connect(socket, SIGNAL(connected()), this, SLOT(connecte()));
    connect(socket, SIGNAL(disconnected()), this, SLOT(deconnecte()));
    connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(erreurSocket(QAbstractSocket::SocketError)));
    connect(monBoutonPushCo, SIGNAL(clicked()), this, SLOT(on_monBoutonPushCo_clicked()));
    connect(monBoutonPushDeco, SIGNAL(clicked()), this, SLOT(on_monBoutonPushDeco_clicked()));
    connect(monBoutonPushManuel, SIGNAL(clicked()), this, SLOT(on_monBoutonPushManuel_clicked()));
    connect(monBoutonPushProfil, SIGNAL(clicked()), this, SLOT(on_monBoutonPushProfil_clicked()));
    connect(monBoutonPushAjoutProfil, SIGNAL(clicked()), this, SLOT(on_monBoutonPushAjoutProfil_clicked()));
}


void Client::demandeConnexion()
{
    QString message = nick->text();
    maSocketClient->envoyerMessage(NOYAU, DEMANDE_CONNEXION, message);
}

void Client::demandeConnexionPass()
{
    QString message = nick->text() + " " + pass->text();
    maSocketClient->envoyerMessage(NOYAU, DEMANDE_CONNEXION_PASS, message);
}


// Tentative de connexion au serveur.
void Client::on_monBoutonPushCo_clicked()
{
    //etat->setText("<font color=#C66800>Connexion en cours</font>");
    socket->abort(); // On désactive les connexions précédentes s'il y en a.
    zoneText->clear();
    zoneText->append("<em>Connexion à <strong>" + ip->text() + "</strong> sur le port <strong>" + port->text() + "</strong>.</em>");
    socket->connectToHost(ip->text(), port->text().toInt()); // On se connecte au serveur demandé.
}

// Deconnexion au serveur.
void Client::on_monBoutonPushDeco_clicked()
{
    socket->close(); // On désactive les connexions précédentes s'il y en a.
}

// Ce slot est appelé lorsque la connexion PHYSIQUE au serveur a réussi
void Client::connecte()
{
    if(pass->text() == "") demandeConnexion();
    else demandeConnexionPass();
}

void Client::on_monBoutonPushAjoutProfil_clicked()
{
    if(!ip->text().isEmpty() && !port->text().isEmpty() && !nick->text().isEmpty() && !nomProfil->text().isEmpty())
    {
        settingsListeProfils->ajouterProfil();
        on_monBoutonPushProfil_clicked();
    }
}

void Client::on_monBoutonPushManuel_clicked()
{
    monBoutonPushManuel->setDisabled(true);
    monBoutonPushProfil->setDisabled(false);
    widgetDeconnecteProfil->setVisible(false);
    widgetDeconnecteManuel->setVisible(true);
}

void Client::on_monBoutonPushProfil_clicked()
{
    monBoutonPushProfil->setDisabled(true);
    monBoutonPushManuel->setDisabled(false);
    widgetDeconnecteManuel->setVisible(false);
    widgetDeconnecteProfil->setVisible(true);
}

void Client::connexionParProfil(const QString &ip, const QString &port, const QString &nick, const QString &pass)
{
    this->ip->setText(ip);
    this->port->setText(port);
    this->pass->setText(pass);
    this->nick->setText(nick);
    on_monBoutonPushCo_clicked();
}

// Ce slot est appelé lorsqu'on est déconnecté du serveur
void Client::deconnecte()
{
    widgetConnecte->hide();
    widgetDeconnecte->show();
    etat->setText("<font color=#C60003>Déconnecté</font>");
    zoneText->append("<em>Déconnecté du serveur <strong>" + socket->peerAddress().toString() + "</strong></em>");
    emit sig_deconnecte();
/*
    for(int i = 0; i <= listeClients->count(); ++i)
    {
        delete listeClients->item(i);
    }
    */
}

// Ce slot est appelé lorsqu'il y a une erreur
void Client::erreurSocket(QAbstractSocket::SocketError erreur)
{
    etat->setText("<font color=#C60003>Déconnecté</font>");
    emit sig_deconnecte();
    switch(erreur) // On affiche un message différent selon l'erreur qu'on nous indique
    {
        case QAbstractSocket::HostNotFoundError:
            zoneText->append("<em>ERREUR : le serveur n'a pas pu être trouvé.</em>");
            break;
        case QAbstractSocket::ConnectionRefusedError:
            zoneText->append("<em>ERREUR : le serveur a refusé la connexion.</em>");
            break;     
        case QAbstractSocket::RemoteHostClosedError:
            //zoneText->append("<em>ERREUR : le serveur a coupé la connexion.</em>");
            break;

    default:
            zoneText->append("<em>ERREUR</em>");
    }

    monBoutonPushCo->setEnabled(true);
}

// Ce slot est appelé lorque le serveur a accepté le client.
void Client::connexionAcceptee()
{
    widgetDeconnecte->hide();
    widgetConnecte->show();
    zoneText->append("<em>Connexion <strong>validée</strong> par le serveur.</em>");
    etat->setText("<font color=#2BC600>Connecté</font>");
    emit sig_connecte();
    //listeClients->addItem(nick->text());
}

// Ce slot est appelé lorque le serveur a refusé le client.
void Client::connexionRefusee(QString message)
{
    zoneText->append("<em>Connexion <strong>refusée</strong> par le serveur (" + message + ").</em>");
}

void Client::envoyerMessage(const QString &message)
{
    maSocketClient->envoyerMessage(CHAT, ENVOYER_A_TOUS, message);
}

void Client::recevoirEnvoyerATous(QString message)
{
    fenetrePrincipale->chatRecevoirEnvoyerATous(message);
}
